package com.cocol.core.utils.log;

import android.util.Log;

/**
 * 描述：Log工具类
 *
 * @author Cocol
 * @company GuangHeBang
 * @date 2015-10-8
 * @email 617882976@qq.com
 */
public class LogUtils {

    private LogUtils() {
        throw new UnsupportedOperationException("LogUtil 不能实例化！");
    }

    /**
     * 获取log显示开关
     */
    public static boolean getIsLogShow() {
        return allowD;
    }

    public static boolean allowD = true;
    public static boolean allowE = true;
    public static boolean allowI = true;
    public static boolean allowV = true;
    public static boolean allowW = true;
    public static boolean allowWtf = true;

    public static String tag = "L";

    /**
     * 用户自定义的log，如果没有那么就直接L本身来处理
     */
    private static ILog mLog;

    public static void setLogger(ILog log) {
        mLog = log;
    }

    private static String addSubTagToContent(String content) {
        StackTraceElement caller = Thread.currentThread().getStackTrace()[4];
        // com.cocol.KlazzName
        String clazzName = caller.getClassName();
        // KlazzName
        clazzName = clazzName.substring(clazzName.lastIndexOf(".") + 1);
        // KlazzName.methodName(Line:188)
        String format = "[发生 => %s.%s$%d] ";
        return String.format(format, clazzName, caller.getMethodName(),
                caller.getLineNumber())
                + content;
    }

    private static String getClazzAndMethod(String clazz) {
        StackTraceElement caller = Thread.currentThread().getStackTrace()[4];

        String clazzName = caller.getClassName();
        clazzName = clazzName.substring(clazzName.lastIndexOf(".") + 1);

        String methodName = caller.getMethodName();

        String format = "Execute %s.%s";
        return String.format(format, clazzName, methodName);
    }

    public static void trace(String clazz) {
        if (!allowD)
            return;
        String content = getClazzAndMethod(clazz);
        Log.d(tag, content);
    }

    public static void d(String content) {
        if (!allowD)
            return;
        content = addSubTagToContent(content);
        if (mLog != null) {
            mLog.d(content);
        } else {
            Log.d(tag, content);
        }
    }

    public static void d(String tag, String content) {
        if (!allowD)
            return;
        content = addSubTagToContent(content);
        if (mLog != null) {
            mLog.d(tag, content);
        } else {
            Log.d(tag, content);
        }
    }

    public static void d(String tag, String content, Throwable tr) {
        if (!allowD)
            return;
        content = addSubTagToContent(content);
        if (mLog != null) {
            mLog.d(tag, content, tr);
        } else {
            Log.d(tag, content, tr);
        }
    }

    public static void e(String content) {
        if (!allowE)
            return;
        content = addSubTagToContent(content);
        if (mLog != null) {
            mLog.e(content);
        } else {
            Log.e(tag, content);
        }
    }

    public static void e(String tag, String content) {
        if (!allowE)
            return;
        content = addSubTagToContent(content);
        if (mLog != null) {
            mLog.e(tag, content);
        } else {
            Log.e(tag, content);
        }
    }

    public static void e(String tag, String content, Throwable tr) {
        if (!allowE)
            return;
        content = addSubTagToContent(content);
        if (mLog != null) {
            mLog.e(tag, content, tr);
        } else {
            Log.e(tag, content, tr);
        }
    }

    public static void i(String content) {
        if (!allowI)
            return;
        content = addSubTagToContent(content);
        if (mLog != null) {
            mLog.i(content);
        } else {
            Log.i(tag, content);
        }
    }

    public static void i(String tag, String content) {
        if (!allowI)
            return;
        content = addSubTagToContent(content);
        if (mLog != null) {
            mLog.i(tag, content);
        } else {
            Log.i(tag, content);
        }
    }

    public static void i(String tag, String content, Throwable tr) {
        if (!allowI)
            return;
        content = addSubTagToContent(content);

        if (mLog != null) {
            mLog.i(tag, content, tr);
        } else {
            Log.i(tag, content, tr);
        }
    }

    public static void v(String content) {
        if (!allowV)
            return;
        content = addSubTagToContent(content);
        if (mLog != null) {
            mLog.v(content);
        } else {
            Log.v(tag, content);
        }
    }

    public static void v(String tag, String content) {
        if (!allowV)
            return;
        content = addSubTagToContent(content);
        if (mLog != null) {
            mLog.v(tag, content);
        } else {
            Log.v(tag, content);
        }
    }

    public static void v(String tag, String content, Throwable tr) {
        if (!allowV)
            return;
        content = addSubTagToContent(content);
        if (mLog != null) {
            mLog.v(tag, content, tr);
        } else {
            Log.v(tag, content, tr);
        }
    }

    public static void w(String content) {
        if (!allowW)
            return;
        content = addSubTagToContent(content);
        if (mLog != null) {
            mLog.w(content);
        } else {
            Log.w(tag, content);
        }
    }

    public static void w(String tag, String content) {
        if (!allowW)
            return;
        content = addSubTagToContent(content);
        if (mLog != null) {
            mLog.w(tag, content);
        } else {
            Log.w(tag, content);
        }
    }

    public static void w(String tag, String content, Throwable tr) {
        if (!allowW)
            return;
        content = addSubTagToContent(content);
        if (mLog != null) {
            mLog.w(tag, content, tr);
        } else {
            Log.w(tag, content, tr);
        }
    }

    public static void w(String tag, Throwable tr) {
        if (!allowW)
            return;
        if (mLog != null) {
            mLog.w(tag, tr);
        } else {
            Log.w(tag, tr);
        }
    }

    public static void wtf(String content) {
        if (!allowWtf)
            return;
        content = addSubTagToContent(content);
        if (mLog != null) {
            mLog.wtf(content);
        } else {
            Log.wtf(tag, content);
        }
    }

    public static void wtf(String tag, String content) {
        if (!allowWtf)
            return;
        content = addSubTagToContent(content);
        if (mLog != null) {
            mLog.wtf(tag, content);
        } else {
            Log.wtf(tag, content);
        }
    }

    public static void wtf(String tag, String content, Throwable tr) {
        if (!allowW)
            return;
        content = addSubTagToContent(content);
        if (mLog != null) {
            mLog.wtf(tag, content, tr);
        } else {
            Log.wtf(tag, content, tr);
        }
    }

    public static void wtf(String tag, Throwable tr) {
        if (!allowW)
            return;
        if (mLog != null) {
            mLog.wtf(tag, tr);
        } else {
            Log.wtf(tag, tr);
        }
    }


    public interface ILog {
        void d(String content);

        void d(String tag, String content);

        void d(String tag, String content, Throwable tr);

        void e(String content);

        void e(String tag, String content);

        void e(String tag, String content, Throwable tr);

        void i(String content);

        void i(String tag, String content);

        void i(String tag, String content, Throwable tr);

        void v(String content);

        void v(String tag, String content);

        void v(String tag, String content, Throwable tr);

        void w(String content);

        void w(String tag, String content);

        void w(String tag, String content, Throwable tr);

        void w(String tag, Throwable tr);

        void wtf(String content);

        void wtf(String tag, String content);

        void wtf(String tag, String content, Throwable tr);

        void wtf(String tag, Throwable tr);
    }

}
